package com.njust.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.njust.Util.AliOssUtil;
import com.njust.Util.PdfUtil;
import com.njust.constant.Constant;
import com.njust.domain.dto.*;
import com.njust.domain.po.PersonnelCapabilitie;
import com.njust.domain.po.Project;
import com.njust.domain.po.TrainTestPaper;
import com.njust.domain.po.User;
import com.njust.domain.vo.TrainPageQueryPersonVO;
import com.njust.domain.vo.TrainPageQueryProjectVO;
import com.njust.domain.vo.TrainPageQueryVO;
import com.njust.exception.*;
import com.njust.mapper.PersonnelCapabilitieMapper;
import com.njust.mapper.ProjectMapper;
import com.njust.mapper.TrainTestPaperMapper;
import com.njust.mapper.UserMapper;
import com.njust.result.Result;
import com.njust.service.TrainService;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

import static com.njust.constant.Constant.*;


/**
 * @version 1.0
 * @Author Imak
 * @Date 2024/11/13 22:37
 * @培训相关功能实现
 */
@Service
@Slf4j
public class TrainServiceImpl implements TrainService {
    @Autowired
    private TrainTestPaperMapper trainMapper;

    @Autowired
    private PersonnelCapabilitieMapper capabilitieMapper;

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AliOssUtil aliOssUtil;
    /**
     * 上传试卷
     *
     * @param trainTestPaperDTO
     */
    @Override
    public void upload_pdf(TrainTestPaperDTO trainTestPaperDTO) {
        String exam_paper = trainTestPaperDTO.getExam_paper();
        Integer project_id = trainTestPaperDTO.getProject_id();
        TrainTestPaper trainTestPaper = TrainTestPaper.builder().project_id(project_id).exam_paper(exam_paper).build();
        // * 判断该试卷是否已经存在 存在则更新 不存在则保存
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("project_id", project_id);
        if (trainMapper.exists(queryWrapper)) {
            trainMapper.update(trainTestPaper, queryWrapper);
        } else {
            trainMapper.insert(trainTestPaper);
        }
    }

    /**
     * 下载试卷
     *
     * @param project_id
     * @return
     * @throws FileNotFoundException
     */
    @Override
    public String download(int project_id) throws FileNotFoundException {
        // 判断试卷是否存在
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("project_id", project_id);
        TrainTestPaper paper = trainMapper.selectOne(queryWrapper);
        if (paper == null) {
            throw new TestPaperNotFindException("支持人员还没有上传试卷");
        }
        return paper.getExam_paper();

    }

    @Override
    public String download_cert(TrainDownloadCertDTO trainDownloadCertDTO) {
        // 判断是否已经完成了要下载的证书的要求
        LambdaQueryWrapper<PersonnelCapabilitie> wrapper = new LambdaQueryWrapper();
        int cert_status = trainDownloadCertDTO.getCert_status();
        wrapper.eq(PersonnelCapabilitie::getUId, trainDownloadCertDTO.getUId())
                .eq(PersonnelCapabilitie::getProject_id, trainDownloadCertDTO.getProject_id())
                .ge(PersonnelCapabilitie::getAssessment_status, cert_status);
        PersonnelCapabilitie personnelCapabilitie = capabilitieMapper.selectOne(wrapper);
        if (cert_status == 1) {
            if (personnelCapabilitie == null) {
                throw new HaveNotCompletedTrainingOrAssessment("培训未完成");
            }
            return personnelCapabilitie.getTraining_cert_link();
        } else {
            if (personnelCapabilitie == null) {
                throw new HaveNotCompletedTrainingOrAssessment("考核未完成");
            }
            return personnelCapabilitie.getAuthorization_cert_link();
        }

    }

    @Override
    public TrainPageQueryPersonVO queryPerson(TrainPageQueryDTO trainPageQueryDTO) {
        PageHelper.startPage(trainPageQueryDTO.getPage(),trainPageQueryDTO.getPageSize());
        Page<TrainPageQueryVO> page = capabilitieMapper.personPageQuery(trainPageQueryDTO.getProject_id());
        long total = page.getTotal();
        List<TrainPageQueryVO> records = page.getResult();
        return TrainPageQueryPersonVO.builder().total(total).records(records).build();
    }

    @Override
    public void updateStatus(int assessment_status, TrainPersonDTO trainPersonDTO) throws Exception {
        // 获取基本信息
        int uId = trainPersonDTO.getUId();
        int project_id = trainPersonDTO.getProject_id();
        String category;
        // 确保需要设置状态时才设置
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("uId", uId);
        wrapper.eq("project_id", project_id);
        wrapper.lt("assessment_status", assessment_status);
        log.info("状态，{}",assessment_status);
        try{
            PersonnelCapabilitie capabilitie = capabilitieMapper.selectOne(wrapper);
            if (capabilitie == null) {
                System.out.println("不需要更新");
                throw new StatusException("状态修改异常！");
            }
            // 设置状态
            QueryWrapper wrapper1 = new QueryWrapper();
            wrapper1.eq("uId", uId);
            capabilitie.setAssessment_status(assessment_status);
            // 获取证书路径
            String location;
            if (assessment_status == 1) {
                location = CERTIFICATES_OF_TRAINING_URL;
                category = "培训证书";
            } else {
                location = CERTIFICATES_OF_AUTHORIZATION_URL;
                category = "考核证书";
            }
            // 获取基本信息
            TrainCreateCertificateDTO certificate = trainMapper.createCertificate(uId, project_id);
            // 获取当前日期
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月", Locale.CHINA);
            String format = dateFormat.format(calendar.getTime());
            dateFormat = new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA);
            String format1 = dateFormat.format(calendar.getTime());
            // 获取code
            String uuId = String.valueOf(uId);
            int len = 6 - uuId.length();
            int lastPart = ThreadLocalRandom.current().nextInt( (int) Math.pow(10, len-1), (int) Math.pow(10, len));
            String lastPartString = String.valueOf(lastPart);
//        String frontPart = "0".repeat(len - lastPartString.length());
//        System.out.println(frontPart);
            String code = calendar.get(Calendar.YEAR) + uuId + lastPart;
            // 赋值map
            Map<String, String> map = new HashMap<>();
            map.put("uName", certificate.getUName());
            map.put("code", code);
            map.put("date1", format);
            map.put("product_name", certificate.getProductName());
            map.put("project_standard_number", certificate.getStandardNumber());
            map.put("project_name", certificate.getProjectName());
            map.put("institution", "名茜生物");
            map.put("date2", format1);
            // 云端文件地址
            String filePath = "";
            try {
                // 生成修改后的pdf文件
                PdfUtil.getPDFUrl(location, TEMPORARY_STORE_CERTIFICATE_URL, FONT_URL, map);

                File file = new File(TEMPORARY_STORE_CERTIFICATE_URL);
                byte[] bFile = Files.readAllBytes(file.toPath());
                String originalFilename = code + category;//原始文件名
                String objectName = originalFilename + ".pdf";
                filePath = aliOssUtil.upload(bFile, objectName);
                file.delete();
            } catch (IOException e) {
                log.error("文件上传失败：{}", e);
                e.printStackTrace();
            }
            Date date = dateFormat.parse(format1);
            if (assessment_status == 1) {
                capabilitie.setTraining_completion(date);
                capabilitie.setTraining_cert_link(filePath);
            } else {
                capabilitie.setAssessment_completion(date);
                capabilitie.setAuthorization_cert_link(filePath);
            }
            log.info("cap",capabilitie);
            capabilitieMapper.update(capabilitie, wrapper1);
        }catch (TooManyResultsException e){
            throw new CBResultsException("人员能力表存在重复数据，查询异常！");
        }

    }
    @Override
    public TrainPageQueryPersonVO queryProject(TrainPageQueryDTO trainPageQueryDTO) {
        PageHelper.startPage(trainPageQueryDTO.getPage(),trainPageQueryDTO.getPageSize());
        Page<TrainPageQueryProjectVO> page = capabilitieMapper.projectSelectPage(trainPageQueryDTO.getProject_id());
        long total = page.getTotal();
        List<TrainPageQueryProjectVO> records = page.getResult();
        return TrainPageQueryPersonVO.builder().total(total).records(records).build();
    }

    /**
     * 增加培训记录
     * @param trainDTO
     */
    @Override
    public void joinInTrain(TrainDTO trainDTO) {
        int project_id=trainDTO.getProject_id();
        int uId=trainDTO.getUId();
        Project project=projectMapper.selectById(project_id);
        User user=userMapper.selectById(uId);
        if(project==null||user==null){
            throw new UserOrProjectNotExist("项目或人员不存在");
        }
        QueryWrapper<PersonnelCapabilitie> wrapper=new QueryWrapper<>();
        wrapper.eq("project_id",project_id)
                .eq("uId",uId);
        int count= Math.toIntExact(capabilitieMapper.selectCount(wrapper));
        if(count>0) {
            //已经有记录
            throw new UserHasInTrainTable("该人员已参加培训，请勿重复提交！");
        }
        PersonnelCapabilitie personnelCapabilitie=new PersonnelCapabilitie();
        BeanUtils.copyProperties(trainDTO,personnelCapabilitie);
        personnelCapabilitie.setAssessment_status(WITHOUT_TRAIN);
        capabilitieMapper.insert(personnelCapabilitie);
    }

}
